home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 2 / Apprentice-Release2.iso / Source Code / C / Frameworks / TransSkel 3.18 / Demos / C Demos / ManyWind / ManyWind.c next >
Encoding:
C/C++ Source or Header  |  1994-10-30  |  8.6 KB  |  365 lines  |  [TEXT/KAHL]

  1. /*
  2.  * Bug: doesn't properly keep bottom of window from going off screen.
  3.  *
  4.  * ManyWind -- TransSkel demonstration
  5.  *
  6.  * This application allows up to twenty windows to be created at once,
  7.  * with the New item under the File menu.  The name of each window
  8.  * appears under the Window menu (which is not created until at least
  9.  * one window exists).  Selecting the window name from the Window menu
  10.  * brings the window to the front.  For every window created, Skel is
  11.  * told to create a new handler.  If the window's close box is clicked,
  12.  * the handler removes the window name from the Window menu, disposes
  13.  * of the window, and removes itself from the window handler list.  If
  14.  * the window was the last window, the Window menu handler removes
  15.  * itself from the menu handler list.
  16.  *
  17.  * When the first window is created, a Color menu also appears.  This
  18.  * allows the color of the content region of the frontmost window to
  19.  * be changed.  It goes away when the last window is closed.
  20.  *
  21.  * To quit, select Quit from the File menu or type command-Q.
  22.  *
  23.  * ManyWind demonstrates dynamic window and menu creation and disposal.
  24.  * It also shows how handler procedures may be shared among handlers
  25.  * for different windows.
  26.  *
  27.  * 21 Apr 88 Version 1.00
  28.  * - Created.  Paul DuBois.
  29.  * 29 Jan 89 Version 1.01
  30.  * - Conversion for TransSkel 2.0.
  31.  * 30 Jan 91 Version 1.02
  32.  * - Conversion for TransSkel 3.00.
  33.  * 05 Jun 93 Version 1.03
  34.  * - Conversion for THINK C 6.0.
  35.  * 13 Nov 93
  36.  * - Added Close item to file menu.
  37.  * 11 Feb 94
  38.  * - Minor revisions and bug fixes.
  39.  * 15 Feb 94
  40.  * - Added item checking for Color and Window menus.
  41.  * 21 Feb 94
  42.  * - Updated for TransSkel 3.11.
  43.  */
  44.  
  45. # include    "TransSkel.h"
  46.  
  47. # define    maxWind    20    /* maximum number of windows existing at once */
  48.  
  49.  
  50. enum                /* menu numbers */
  51. {
  52.     aMenuNum = skelAppleMenuID,    /* Apple menu */
  53.     fMenuNum,                    /* File menu */
  54.     wMenuNum,                    /* Window menu */
  55.     cMenuNum                    /* Color menu */
  56. };
  57.  
  58.  
  59. enum                /* File menu item numbers */
  60. {
  61.     newWind = 1,
  62.     closeWind,
  63.     /* --- */
  64.     quitApp = 4
  65. };
  66.  
  67. enum                /* Color menu items numbers */
  68. {
  69.     cWhite = 1,
  70.     cLtGray,
  71.     cGray,
  72.     cDkGray,
  73.     cBlack
  74. };
  75.  
  76.  
  77. static void MakeWindow(void);
  78.  
  79.  
  80. MenuHandle    fileMenu;
  81. MenuHandle    windowMenu;
  82. MenuHandle    colorMenu;
  83.  
  84. short    windCount = 0;    /* number of currently existing windows */
  85. long    windNum = 0;    /* id of last window created */
  86.  
  87.  
  88. /* ------------- */
  89. /* Menu handling */
  90. /* ------------- */
  91.  
  92.  
  93. static pascal void
  94. DoFileMenu (short item)
  95. {
  96. WindowPtr    w;
  97.  
  98.     switch (item)
  99.     {
  100.         case newWind:                    /* make a new window */
  101.             MakeWindow ();
  102.             break;
  103.         case closeWind:
  104.             SkelClose (FrontWindow ());
  105.             break;
  106.         case quitApp:                    /* tell SkelEventLoop() to quit */
  107.             SkelStopEventLoop ();
  108.             break;
  109.     }
  110. }
  111.  
  112.  
  113. static pascal void
  114. DoWindowMenu (short item)
  115. {
  116. Str255        iTitle, wTitle;
  117. WindowPtr    w;
  118.  
  119.     GetItem (windowMenu, item, iTitle);    /* get window name */
  120.     for (w = FrontWindow (); w != nil; w = (WindowPtr) ((WindowPeek)w)->nextWindow)
  121.     {
  122.         GetWTitle (w, wTitle);
  123.         if (EqualString (iTitle, wTitle, false, true))
  124.         {
  125.             SelectWindow (w);
  126.             break;
  127.         }
  128.     }
  129. }
  130.  
  131.  
  132. /*
  133.  * Change the background pattern of the frontmost window.
  134.  * Ignore if the front window is a DA window.
  135.  */
  136. static pascal void
  137. DoColorMenu (short item)
  138. {
  139. WindowPtr    w;
  140.  
  141.     w = FrontWindow ();
  142.     if (((WindowPeek) w)->windowKind < 0) return;    /* front is DA window */
  143.     switch (item)
  144.     {
  145.         case cWhite:    BackPat ((ConstPatternParam) &qd.white); break;
  146.         case cLtGray:    BackPat ((ConstPatternParam) &qd.ltGray); break;
  147.         case cGray:        BackPat ((ConstPatternParam) &qd.gray); break;
  148.         case cDkGray:    BackPat ((ConstPatternParam) &qd.dkGray); break;
  149.         case cBlack:    BackPat ((ConstPatternParam) &qd.black); break;
  150.     }
  151.     SetWRefCon (w, item);        /* save item number for menu checkmarking */
  152.     EraseRect (&w->portRect);
  153. }
  154.  
  155.  
  156. static pascal void
  157. DoMClobber (MenuHandle m)
  158. {
  159.     DisposeMenu (m);
  160. }
  161.  
  162.  
  163. static void
  164. SetItemEnableState (MenuHandle m, short item, Boolean state)
  165. {
  166.     if (state)
  167.         EnableItem (m, item);
  168.     else
  169.         DisableItem (m, item);
  170. }
  171.  
  172.  
  173. /*
  174.  * Adjust menus when mouse click occurs in menu bar.
  175.  * File menu:
  176.  * - New is enabled if window count hasn't exceeded limit.
  177.  * - Close is enabled if there is a window visible.
  178.  * Color menu:
  179.  * - Check item corresponding to color of frontmost window.
  180.  * Window menu:
  181.  * - Check item corresponding to frontmost window.
  182.  */
  183.  
  184. static pascal void
  185. AdjustMenus (void)
  186. {
  187. short    nItems, i;
  188. Str255    iTitle, wTitle;
  189. short    mark;
  190.  
  191.     SetItemEnableState(fileMenu, newWind, windCount < maxWind);
  192.     SetItemEnableState(fileMenu, closeWind, FrontWindow() != (WindowPtr) nil);
  193.     if (windCount > 0)
  194.     {
  195.         for (i = cWhite; i <= cBlack; i++)
  196.         {
  197.             mark = (GetWRefCon (FrontWindow ()) == i ? checkMark : noMark);
  198.             SetItemMark (colorMenu, i, mark);
  199.         }
  200.         GetWTitle (FrontWindow(), wTitle);
  201.         nItems = CountMItems (windowMenu);
  202.         for (i = 1; i <= nItems; i++)
  203.         {
  204.             GetItem (windowMenu, i, iTitle);
  205.             mark = (EqualString (iTitle, wTitle, false, true) ? checkMark : noMark);
  206.             SetItemMark (windowMenu, i, mark);
  207.         }
  208.     }
  209. }
  210.  
  211.  
  212. /* --------------- */
  213. /* Window handling */
  214. /* --------------- */
  215.  
  216.  
  217. static pascal void
  218. DoWUpdate (Boolean resized)
  219. {
  220. WindowPtr    w;
  221.  
  222.     GetPort (&w);
  223.     EraseRect (&w->portRect);    /* repaint w/background pattern */
  224. }
  225.  
  226.  
  227. /*
  228.  * Mouse was clicked in close box.  Remove the window handler (which
  229.  * causes the window to be disposed of), and delete the window title
  230.  * from the Window menu.  If the window was the last one, delete the
  231.  * Window and Color menus entirely.
  232.  *
  233.  * Skel makes sure the port is pointing to the appropriate window, so
  234.  * this procedure can determine which window had its close box clicked,
  235.  * without being told explicitly.
  236.  */
  237.  
  238. static pascal void
  239. DoWClose (void)
  240. {
  241. WindowPtr    w;
  242.  
  243.     GetPort (&w);            /* window to be closed */
  244.     SkelRmveWind (w);
  245. }
  246.  
  247.  
  248. /*
  249.  * Dispose of window.  Skel makes sure the port is pointing to the
  250.  * appropriate window, so this procedure can determine which window
  251.  * is to be disposed, of without being told explicitly.
  252.  *
  253.  * Also delete the window title from the Window menu.  If the window
  254.  * was the last one, delete the Window and Color menus entirely.
  255.  */
  256.  
  257. static pascal void
  258. DoWClobber (void)
  259. {
  260. WindowPtr    w;
  261. short        i, mItems;
  262. Str255        iTitle, wTitle;
  263.  
  264.     GetPort (&w);            /* window to be closed */
  265.     GetWTitle (w, wTitle);
  266.     DisposeWindow (w);
  267.     if (--windCount == 0)
  268.     {
  269.         SkelRmveMenu (windowMenu);    /* last window - clobber menus */
  270.         SkelRmveMenu (colorMenu);
  271.     }
  272.     else
  273.     {
  274.         for (i = 1, mItems = CountMItems (windowMenu); i <= mItems; ++i)
  275.         {
  276.             GetItem (windowMenu, i, iTitle);
  277.             if (EqualString (iTitle, wTitle, false, true))
  278.             {
  279.                 DelMenuItem (windowMenu, i);
  280.                 break;
  281.             }
  282.         }
  283.     }
  284. }
  285.  
  286.  
  287. /*
  288.  * Make new window.  Locate at (100, 100) if no other windows, else
  289.  * offset slightly from front window.  The window title is the next
  290.  * window number (1, 2, 3, ...).  If this is the first window, create
  291.  * the Window and Color menus.  Add the window title as the last item
  292.  * of the Window menu.
  293.  *
  294.  * If the maximum window count is reached, disable New in the
  295.  * File menu.
  296.  */
  297.  
  298. static void
  299. MakeWindow (void)
  300. {
  301. WindowPtr    w;
  302. Rect        r;
  303. Str255        s;
  304.  
  305.     if ((w = FrontWindow ()) == (WindowPtr) nil)
  306.         SetRect (&r, 100, 100, 300, 250);
  307.     else
  308.     {
  309.         SkelGetWindContentRect (w, &r);
  310.         OffsetRect (&r, 20, 20);
  311.         if (r.left > 480 || r.top > 300)    /* keep on screen */
  312.             OffsetRect (&r, 40 - r.left, 40 - r.top);
  313.     }
  314.     NumToString (++windNum, s);
  315.     if (SkelQuery (skelQHasColorQD))
  316.         w = NewCWindow (nil, &r, s, true, noGrowDocProc, (WindowPtr) -1L, true, 0L);
  317.     else
  318.         w = NewWindow (nil, &r, s, true, noGrowDocProc, (WindowPtr) -1L, true, 0L);
  319.     (void) SkelWindow (w,
  320.                 nil,        /* mouseclicks */
  321.                 nil,        /* key clicks */
  322.                 DoWUpdate,    /* updates */
  323.                 nil,        /* activate/deactivate events */
  324.                 DoWClose,    /* close window, remove from menu */
  325.                 DoWClobber,    /* dispose of window */
  326.                 nil,        /* idle proc */
  327.                 false);        /* irrelevant, since no idle proc */
  328.  
  329.     if (windCount++ == 0)    /* if first window, create new menus */
  330.     {
  331.         colorMenu = NewMenu (cMenuNum, "\pColor");
  332.         AppendMenu (colorMenu, "\pWhite;Light Gray;Gray;Dark Gray;Black");
  333.         (void) SkelMenu (colorMenu, DoColorMenu, DoMClobber, false, false);
  334.         windowMenu = NewMenu (wMenuNum, "\pWindow");
  335.         (void) SkelMenu (windowMenu, DoWindowMenu, DoMClobber, false, true);
  336.     }
  337.     AppendMenu (windowMenu, s);
  338.     SetWRefCon (w, cWhite);
  339. }
  340.  
  341.  
  342. static void
  343. SetupMenus (void)
  344. {
  345.     SkelApple (nil, nil);                        /* initialize Apple menu */
  346.     fileMenu = NewMenu (fMenuNum, "\pFile");    /* make File menu handler */
  347.     AppendMenu (fileMenu, "\pNew/N;Close/W;(-;Quit/Q");
  348.     (void) SkelMenu (fileMenu, DoFileMenu, DoMClobber, false, true);
  349.     SkelSetMenuHook (AdjustMenus);
  350. }
  351.  
  352.  
  353. /* ------------ */
  354. /* Main program */
  355. /* ------------ */
  356.  
  357. int
  358. main (void)
  359. {
  360.     SkelInit ((SkelInitParamsPtr) nil);            /* initialize */
  361.     SetupMenus ();
  362.     SkelEventLoop ();                            /* loop 'til Quit selected */
  363.     SkelCleanup ();                                /* clean up */
  364. }
  365.